#pragma once
#include "DMass.h"
#include "DMatrix3.h"
#include "DVector4.h"
#include "DVector3.h"
#include "Geometries/DTriMesh.h"

namespace Skill
{
	namespace Ode
	{		
		void DMass::CollectManagedMemory()
		{
			_Center = nullptr;
			_InteriaTensor = nullptr;
		}

		VALUE_PROP_DEFINITION_GETSET(DMass,_This->mass,dReal,Mass);
		REF_PROP_DEFINITION_GET_FROM_REF(DMass,c,DVector4,Center);
		void DMass::Center::set(DVector4^ value)
		{
			for(int i=0;i<4;i++)
				_This->c[i] = value->_This[i];			
		}
		REF_PROP_DEFINITION_GET_FROM_REF(DMass,I,DMatrix3,InteriaTensor);
		void DMass::InteriaTensor::set(DMatrix3^ value)
		{
			for(int i=0;i<4;i++)
				_This->I[i] = value->_This[i];			
		}

		bool DMass::Check(DMass^ m)
		{
			return (dMassCheck(m->_This) == 1)? true : false;
		}

		void DMass::SetZero()
		{
			dMassSetZero(_This);
		}
		DMass^ DMass::Zero::get()
		{
			DMass^ d = gcnew DMass();
			d->SetZero();
			return d;
		}

		void DMass::SetParameters(dReal themass,
			dReal cgx, dReal cgy, dReal cgz,
			dReal I11, dReal I22, dReal I33,
			dReal I12, dReal I13, dReal I23)
		{
			dMassSetParameters(_This,themass,cgx,cgy,cgz,I11,I22,I33,I12, I13, I23);
		}

		DMass^ DMass::FromParameters(dReal themass,
			dReal cgx, dReal cgy, dReal cgz,
			dReal I11, dReal I22, dReal I33,
			dReal I12, dReal I13, dReal I23)
		{
			DMass^ d = gcnew DMass();
			d->SetParameters(themass,cgx,cgy,cgz,I11,I22,I33,I12, I13, I23);
			return d;
		}

		void DMass::SetSphere(dReal density, dReal radius)
		{
			dMassSetSphere(_This,density, radius);
		}
		DMass^ DMass::FromSphere(dReal density, dReal radius)
		{
			DMass^ d = gcnew DMass();
			dMassSetSphere(d->_This,density, radius);
			return d;
		}

		void DMass::SetSphereTotal(dReal total_mass, dReal radius)
		{
			dMassSetSphereTotal(_This,total_mass, radius);
		}
		DMass^ DMass::FromSphereTotal(dReal total_mass, dReal radius)
		{
			DMass^ d = gcnew DMass();
			dMassSetSphereTotal(d->_This,total_mass, radius);
			return d;
		}

		void DMass::SetCapsule(dReal density, int direction, dReal radius, dReal length)
		{
			dMassSetCapsule(_This,density, direction, radius, length);
		}
		DMass^ DMass::FromCapsule(dReal density, int direction, dReal radius, dReal length)
		{
			DMass^ d = gcnew DMass();
			dMassSetCapsule(d->_This,density, direction, radius, length);
			return d;
		}

		void DMass::SetCapsuleTotal(dReal total_mass, int direction, dReal radius, dReal length)
		{
			dMassSetCapsuleTotal(_This, total_mass, direction, radius, length);
		}
		DMass^ DMass::FromCapsuleTotal(dReal total_mass, int direction, dReal radius, dReal length)
		{
			DMass^ d = gcnew DMass();
			dMassSetCapsuleTotal(d->_This, total_mass, direction, radius, length);
			return d;
		}

		void DMass::SetCylinder(dReal density, int direction, dReal radius, dReal length)
		{
			dMassSetCylinder(_This,density, direction, radius, length);
		}
		DMass^ DMass::FromCylinder(dReal density, int direction, dReal radius, dReal length)
		{
			DMass^ d = gcnew DMass();
			dMassSetCylinder(d->_This,density, direction, radius, length);
			return d;
		}

		void DMass::SetCylinderTotal(dReal total_mass, int direction, dReal radius, dReal length)
		{
			dMassSetCylinderTotal(_This,total_mass, direction, radius, length);
		}
		DMass^ DMass::FromCylinderTotal(dReal total_mass, int direction, dReal radius, dReal length)
		{
			DMass^ d = gcnew DMass();
			dMassSetCylinderTotal(d->_This,total_mass, direction, radius, length);
			return d;
		}

		void DMass::SetCappedCylinder(dReal density, int direction, dReal radius, dReal length)
		{
			dMassSetCappedCylinder(_This,density, direction, radius, length);
		}
		DMass^ DMass::FromCappedCylinder(dReal density, int direction, dReal radius, dReal length)
		{
			DMass^ d = gcnew DMass();
			dMassSetCappedCylinder(d->_This,density, direction, radius, length);
			return d;
		}

		void DMass::SetCappedCylinderTotal(dReal total_mass, int direction, dReal radius, dReal length)
		{
			dMassSetCappedCylinderTotal(_This,total_mass, direction, radius, length);
		}
		DMass^ DMass::FromCappedCylinderTotal(dReal total_mass, int direction, dReal radius, dReal length)
		{
			DMass^ d = gcnew DMass();
			dMassSetCappedCylinderTotal(d->_This,total_mass, direction, radius, length);
			return d;
		}

		void DMass::SetBox(dReal density, dReal lx, dReal ly, dReal lz)
		{
			dMassSetBox(_This,density, lx, ly, lz);
		}
		DMass^ DMass::FromBox(dReal density, dReal lx, dReal ly, dReal lz)
		{
			DMass^ d = gcnew DMass();
			dMassSetBox(d->_This,density, lx, ly, lz);
			return d;
		}

		void DMass::SetBox(dReal density, DVector3^ l)
		{
			dMassSetBox(_This,density, l->_This[0], l->_This[1], l->_This[2]);
		}
		DMass^ DMass::FromBox(dReal density, DVector3^ l)
		{
			DMass^ d = gcnew DMass();
			dMassSetBox(d->_This,density, l->_This[0], l->_This[1], l->_This[2]);
			return d;
		}

		void DMass::SetBoxTotal(dReal total_mass, dReal lx, dReal ly, dReal lz)
		{
			dMassSetBoxTotal(_This,total_mass, lx, ly, lz);
		}
		DMass^ DMass::FromBoxTotal(dReal total_mass, dReal lx, dReal ly, dReal lz)
		{
			DMass^ d = gcnew DMass();
			dMassSetBoxTotal(d->_This,total_mass, lx, ly, lz);
			return d;
		}

		void DMass::SetBoxTotal(dReal total_mass, DVector3^ l)
		{
			dMassSetBoxTotal(_This,total_mass, l->_This[0], l->_This[1], l->_This[2]);
		}
		DMass^ DMass::FromBoxTotal(dReal total_mass, DVector3^ l)
		{
			DMass^ d = gcnew DMass();
			dMassSetBoxTotal(d->_This,total_mass, l->_This[0], l->_This[1], l->_This[2]);
			return d;
		}

		void DMass::SetTrimesh(dReal density, DTriMesh^ mesh)
		{
			dMassSetTrimesh(_This,density,mesh->_Geom());
		}
		DMass^ DMass::FromTrimesh(dReal density, DTriMesh^ mesh)
		{
			DMass^ d = gcnew DMass();
			dMassSetTrimesh(d->_This,density,mesh->_Geom());
			return d;
		}

		void DMass::SetTrimeshTotal(dReal total_mass, DTriMesh^ mesh)
		{
			dMassSetTrimeshTotal(_This,total_mass, mesh->_Geom());
		}
		DMass^ DMass::FromTrimeshTotal(dReal total_mass, DTriMesh^ mesh)
		{
			DMass^ d = gcnew DMass();
			dMassSetTrimeshTotal(d->_This,total_mass, mesh->_Geom());
			return d;
		}

		void DMass::Adjust(dReal newmass)
		{
			dMassAdjust(_This,newmass);
		}

		void DMass::Translate(dReal x, dReal y, dReal z)
		{
			dMassTranslate(_This,x,y,z);
		}
		void DMass::Translate(DVector3^ t)
		{
			dMassTranslate(_This,t->_This[0],t->_This[1],t->_This[2]);
		}
		void DMass::Rotate(DMatrix3^ r)
		{
			dMassRotate(_This,r->_This);
		}
		void DMass::Add(DMass^ b)
		{
			dMassAdd(_This,b->_This);
		}
	}
}